package com.henriquevilela.drumtrainer.core.input;

import java.util.List;
import java.util.Vector;

import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Transmitter;

/**
 * @author Henrique de Souza Vilela
 * henrique.vilela@gmail.com
 */
public class MIDIInputDevice implements Receiver {

	private MidiDevice inputDevice;

	private List<MIDIInputDeviceListener> listenerList;
	
	public MIDIInputDevice() {
		listenerList = new Vector<MIDIInputDeviceListener>();
	}

	public void addMIDIInputDeviceListener(MIDIInputDeviceListener listener) {
		listenerList.add(listener);
	}

	public List<MidiDevice.Info> getAvaliableDeviceList() {
		List<MidiDevice.Info> devices = new Vector<MidiDevice.Info>();

		for (MidiDevice.Info info : MidiSystem.getMidiDeviceInfo()) {
			try {
				MidiSystem.getMidiDevice(info);
				devices.add(info);
			} catch (MidiUnavailableException exception) {
				// do nothing
			}
		}

		return devices;
	}

	public void setInputDevice(MidiDevice.Info inputDeviceInfo) throws MidiUnavailableException {
		inputDevice = MidiSystem.getMidiDevice(inputDeviceInfo);
		inputDevice.open();

		Transmitter transmiter = inputDevice.getTransmitter();
		transmiter.setReceiver(this);
	}

	public void send(MidiMessage message, long timeStamp) {
		if (message instanceof ShortMessage) {
			ShortMessage shortMessage = (ShortMessage) message;

			int key = shortMessage.getData1();
			int velocity = shortMessage.getData2();

			fireNotePlayed(key, velocity);
		}
	}

	private void fireNotePlayed(int key, int velocity) {
		for (MIDIInputDeviceListener listener : listenerList) {
			listener.notePlayed(key, velocity);
		}
	}

	public void close() {
		// do nothing
	}
}
